import React from "react";
/**
 * 面试考点：react事件绑定跟原生事件绑定有什么区别？
 * react事件绑定不是绑定到具体的dom身上（因为绑定在每一个dom身上比较消耗内存），
 * 而是采用事件代理的模式绑定到了根节点root的身上，
 * 通过浏览器控制台->元素（Elements）->事件侦听器（Event Listence）可以进行验证。
 * --元素触发事件时，会冒泡到根节点，根节点会通过事件的target事件源找到是哪个元素真实触发的，
 * --然后从这个触发的元素到顶点之间所有的节点都查一查是否含有该事件，如果有就执行
 *
 * 既然react事件没有绑定到dom上，那为什么还有Event对象呢？
 * 和普通浏览器一样，事件handler会被自动传入一个event对象，这个对象和普通浏览器event对象所包含的方法和属性都基本一致，
 * 不同的是React中的event对象不是浏览器提供的，而是它自己内部构建的
 * 它同样具有e.stopPropagation（阻止冒泡）,e.preventDefault（清除默认操作）这种常用的方法
 *
 */

function Hello() {
    const clickFn = (e) => {
        //阻止默认行为
        e.preventDefault();
        console.log("函数组件的点击事件1触发了");
    };
    const clickFn2 = (val) => {
        console.log(val);
        console.log("函数组件的点击事件2触发了");
    };
    const clickFn3 = (e, val) => {
        //阻止默认行为
        e.preventDefault();
        console.log(val);
        console.log("函数组件的点击事件3触发了");
    };
    return (
        <>
            {/* 注意这里调用clickFn的写法不加(),如果加了()就变成自动执行函数了
          --不加()，当组件渲染时会找到名为clickFn的函数添加到onClick事件中，当onClick事件触发时clickFn才会被调用
          --而加了()后，当组件渲染时找到了名为clickFn的函数后就因为加了()的原因当场就调用执行了clickFn函数，
            clickFn函数的执行结果被添加到了onClick事件中，即在组件渲染时clickFn函数就被调用执行了，此时onClick事件中绑定的是clickFn函数的返回值

      */}
            <a href='http://www.baidu.com' onClick={clickFn}>
                hello1
            </a>
            {/* 比较推荐的写法：使用箭头函数调用事件，可以避免类组件中this指向问题 */}
            {/* 传参 */}
            <a
                href='http://www.baidu.com'
                onClick={() => clickFn2("这是参数2")}>
                hello2
            </a>
            {/* 传参和e结合 */}
            <a
                href='http://www.baidu.com'
                onClick={(e) => clickFn3(e, "这是参数3")}>
                hello3
            </a>
        </>
    );
}

class HelloClass extends React.Component {
    //事件回调函数（标准写法，避免this指向问题）
    // 这样写 回调函数中的this指向的时当前的组件实例对象
    clickFn = (e) => {
        //阻止默认行为
        e.preventDefault();
        console.log("类组件的点击事件1触发了");
    };
    clickFn2 = (val) => {
        console.log(val);
        console.log("类组件的点击事件2触发了");
    };
    clickFn3 = (e, val) => {
        e.preventDefault();
        console.log(val);
        console.log("类组件的点击事件3触发了");
    };
    render() {
        return (
            <>
                <div>
                    <a href='http://www.baidu.com' onClick={this.clickFn}>
                        类组件的点击事件
                    </a>
                </div>
                {/* 传参 */}
                <a
                    href='http://www.baidu.com'
                    onClick={() => this.clickFn2("这是参数2")}>
                    类组件的点击事件2
                </a>
                {/* 传参和e结合 */}
                <a
                    href='http://www.baidu.com'
                    onClick={(e) => this.clickFn3(e, "这是参数3")}>
                    类组件的点击事件3
                </a>
            </>
        );
    }
}
function App() {
    return (
        <div className='App'>
            {/* 渲染hello组件 */}
            <Hello></Hello>
            {/* 渲染HelloClass类组件 */}
            <HelloClass></HelloClass>
        </div>
    );
}

export default App;
